#include "stdafx.h"
#include "BatchedModel.h"

using namespace MomogenkyouSystem;

BatchedModel::BatchedModel()
{

}

BatchedModel::~BatchedModel()
{
	m_Materials.clear();
	m_MaterialCount = 0;
	m_pMesh->Release();
}

bool	BatchedModel::Load(const std::string & Directory, const std::string & Filename)
{
	
	LPD3DXBUFFER	_MaterialBuffer;
	LPD3DXBUFFER	_EffectBuffer;

	std::string		_FilePath = (Directory + Filename).c_str();

	HRESULT _Result = D3DXLoadMeshFromXA(	_FilePath.c_str(), D3DXMESH_SYSTEMMEM, 
											GraphicsSystem::Device, NULL, &_MaterialBuffer, &_EffectBuffer, 
											&m_MaterialCount, &m_pMesh);

	ASSERT(_Result == S_OK, "Unable to load XMesh");

	//D3DXMATERIAL		* _pMaterials	= (D3DXMATERIAL *)		_MaterialBuffer->GetBufferPointer();
	D3DXEFFECTINSTANCE	* _pEffect		= (D3DXEFFECTINSTANCE *)_EffectBuffer->GetBufferPointer();

	m_Materials.assign(m_MaterialCount, Material());

	for(DWORD i = 0; i < m_MaterialCount; i++)
	{
		if (_pEffect[i].pEffectFilename)
		{
			std::string _EffectPath		=	Directory + _pEffect[i].pEffectFilename;
			m_Materials[i].PrepareEffectFile(Directory, _EffectPath, &_pEffect[i]);
			m_Materials[i].PrepareStandardGlobalParams(	&GraphicsSystem::param_matView, 
														&GraphicsSystem::param_matProjection, 
														&GraphicsSystem::param_vSunLight);
		}
	}

	_MaterialBuffer->Release();
	_EffectBuffer->Release();
	return true;
}


void	BatchedModel::RenderOneMesh()
{
	size_t _NumOfPass = 0;
	for(size_t i = 0; i < m_MaterialCount; i++)
	{
		m_Materials[i].Effect->Begin(&_NumOfPass, 0);

		for(size_t j = 0; j < _NumOfPass; j++)
		{
			m_Materials[i].Effect->BeginPass(j);
			m_pMesh->DrawSubset(i);
			m_Materials[i].Effect->EndPass();
		}
		m_Materials[i].Effect->End();
	}	
}

void	BatchedModel::RenderManyMesh(const std::vector<ModelRenderable *>	& List)
{
	size_t			_NumOfPass = 0;
	//EffectParameter	_MatWorld;

	for(size_t i = 0; i < m_MaterialCount; i++)
	{
		//_MatWorld = m_Materials[i].GetParameter("matWorld");
		m_Materials[i].Effect->ApplyParameterBlock(m_Materials[i].Param_StandardGlobals);
		m_Materials[i].Effect->Begin(&_NumOfPass, 0);


		for(size_t k = 0; k < List.size(); k++)
		{
			if(!List[k]->Visible())	continue;

			//_MatWorld.SetMatrix(&List[k]->matWorld);
			//	Assume the Renderable creates a block.
			m_Materials[i].Effect->ApplyParameterBlock(List[k]->EffectBlock());

			for(size_t j = 0; j < _NumOfPass; j++)
			{
				m_Materials[i].Effect->BeginPass(j);
				m_pMesh->DrawSubset(i);
				m_Materials[i].Effect->EndPass();
			}
		}
		m_Materials[i].Effect->End();
	}
}